import os
import re

import pandas as pd
from pandas import DataFrame


def standardize_column_name(df: DataFrame):
    column_names = []
    for column in df.columns:
        column_names.append(column.replace(' ', '_').lower())

    df.columns = column_names


def format_millisecond(millisecond):
    return format(millisecond, ',.0f')


def analyze(path: str, is_new_version: bool):
    df: DataFrame = pd.read_csv(path)

    standardize_column_name(df)

    # Add two columns
    if is_new_version:
        df['created'] = df['creating'] + df['created']
        df['started'] = df['starting'] + df['started']

    statistics_dict = {}

    print(f'Total number: {df.shape[0]}')
    statistics_dict['batch_size'] = df.shape[0]

    #
    # Calculate statistics of creation.
    #
    create_success_series = df['mark'].str.contains('creation', na=False)
    create_success_df = df[create_success_series]
    created_average = create_success_df['created'].mean()
    created_standard_deviation = create_success_df['created'].std()
    print(f'Number of created: {create_success_df.shape[0]}')
    print(f'Average time of creating: {format_millisecond(created_average)} milliseconds')
    print(f'Standard deviation: {format_millisecond(created_standard_deviation)} milliseconds')
    statistics_dict['created_count'] = create_success_df.shape[0]
    statistics_dict['created_avg'] = format_millisecond(created_average)
    statistics_dict['created_std'] = format_millisecond(created_standard_deviation)

    #
    # Calculate statistics of starting execution.
    #
    start_success_series = df['mark'].str.contains('execution', na=False)
    start_success_df = df[start_success_series]
    start_average = start_success_df['started'].mean()
    start_standard_deviation = start_success_df['started'].std()
    print(f'Number of started: {start_success_df.shape[0]}')
    print(f'Average time of starting: {format_millisecond(start_average)} milliseconds')
    print(f'Standard deviation: {format_millisecond(start_standard_deviation)} milliseconds')
    statistics_dict['started_count'] = start_success_df.shape[0]
    statistics_dict['started_avg'] = format_millisecond(start_average)
    statistics_dict['started_std'] = format_millisecond(start_standard_deviation)

    start_success_df = DataFrame(start_success_df)
    start_success_df['completed'] = \
        start_success_df['created'] + \
        start_success_df['waiting'] + \
        start_success_df['started']
    completed_average = start_success_df['completed'].mean()
    completed_standard_deviation = start_success_df['completed'].std()
    print(f'Average time of completion: {format_millisecond(completed_average)} milliseconds')
    print(f'Standard deviation: {format_millisecond(completed_standard_deviation)} milliseconds')
    statistics_dict['completed_avg'] = format_millisecond(completed_average)
    statistics_dict['completed_std'] = format_millisecond(completed_standard_deviation)

    return statistics_dict


def main():
    report_dir_path = r'.\CSV'

    file_names = os.listdir(report_dir_path)

    def csv_file_name_predict(file_name: str):
        return file_name.find('report') > -1 and file_name.endswith('.csv')

    csv_file_names = list(filter(csv_file_name_predict, file_names))

    statistics_data = []
    for csv_file_name in csv_file_names:
        report_info_dict = {}

        csv_file_name_pattern = re.compile(r'report_(\d\.\d)_batch_(\d+)')
        match = csv_file_name_pattern.match(csv_file_name)
        report_info_dict['api_ver'] = match.group(1)
        # report_info_dict['batch_size'] = match.group(2)

        print('-' * 80)
        print(f'Analyze {csv_file_name}')
        is_new_ver = csv_file_name.startswith('report_2')
        statistics_dict = analyze(os.path.join(report_dir_path, csv_file_name), is_new_ver)
        print()

        statistics_data.append({**report_info_dict, **statistics_dict})

    statistics_df = DataFrame(statistics_data)
    statistics_df.to_csv(os.path.join(report_dir_path, 'statistics.csv'))


if __name__ == '__main__':
    main()
